// yaml-comment-utils-advanced.js
import { parseDocument } from 'yaml';

/**
 * 获取 YAML 文档中指定路径的注释信息（高级版）
 * @param {string} yamlContent - YAML 文档内容
 * @param {string|string[]} path - 键的路径
 * @param {object} options - 配置选项
 * @returns {object|null} 包含注释信息的对象
 */
export function getCommentByPath(yamlContent, path, options = {}) {
  const { separator = '.', smartParse = true } = options;
  const doc = parseDocument(yamlContent);

  // 智能解析路径
  let pathArray;
  if (Array.isArray(path)) {
    pathArray = path;
  } else if (smartParse) {
    // 智能解析：检测是否包含数组索引
    pathArray = parsePath(path, separator);
  } else {
    pathArray = path.split(separator).filter((p) => p !== '');
  }

  if (pathArray.length === 0) {
    return null;
  }

  let currentNode = doc.contents;
  let targetNode = null;
  let parentNode = null;

  for (let i = 0; i < pathArray.length; i++) {
    const segment = pathArray[i];

    if (!currentNode) {
      return null;
    }

    // 保存父节点
    parentNode = currentNode;

    if (currentNode.items) {
      const isMap = currentNode.items.some((item) => item.key !== undefined);

      if (isMap) {
        // 处理 Map
        const pair = currentNode.items.find((item) => {
          const keyValue = item.key?.value;
          return keyValue === segment || String(keyValue) === segment;
        });

        if (!pair) {
          return null;
        }

        if (i === pathArray.length - 1) {
          targetNode = {
            type: 'pair',
            node: pair,
            parent: parentNode,
          };
          break;
        } else {
          currentNode = pair.value;
        }
      } else {
        // 处理 Seq (数组)
        const index = parseInt(segment);
        if (isNaN(index) || index < 0 || index >= currentNode.items.length) {
          return null;
        }

        const item = currentNode.items[index];

        if (i === pathArray.length - 1) {
          targetNode = {
            type: 'item',
            node: item,
            parent: parentNode,
            index: index,
          };
          break;
        } else {
          currentNode = item;
        }
      }
    } else {
      // 标量节点
      if (i === pathArray.length - 1) {
        targetNode = {
          type: 'scalar',
          node: currentNode,
          parent: parentNode,
        };
      } else {
        return null;
      }
    }
  }

  // 提取注释信息
  if (targetNode) {
    const { type, node, parent, index } = targetNode;

    if (type === 'pair') {
      // Map 的键值对
      return {
        value: node.value?.value !== undefined ? node.value.value : node.value?.toString(),
        comment: node.value?.comment || null,
        commentBefore: node.value?.commentBefore || null,
        keyComment: node.key?.comment || null,
        keyCommentBefore: node.key?.commentBefore || null,
        type: 'pair',
        nodeType: node.value?.type || 'unknown',
      };
    } else if (type === 'item') {
      // 数组项
      let comment = node?.comment || null;
      let commentBefore = node?.commentBefore || null;

      // 对于数组中的标量值，注释可能直接附在节点上
      if (node && typeof node === 'object') {
        comment = comment || node.comment || null;
        commentBefore = commentBefore || node.commentBefore || null;
      }

      return {
        value: node?.value !== undefined ? node.value : node?.toString(),
        comment: comment,
        commentBefore: commentBefore,
        type: 'item',
        index: index,
        nodeType: node?.type || 'unknown',
      };
    } else if (type === 'scalar') {
      // 标量值
      return {
        value: node?.value !== undefined ? node.value : node?.toString(),
        comment: node?.comment || null,
        commentBefore: node?.commentBefore || null,
        type: 'scalar',
        nodeType: node?.type || 'unknown',
      };
    }
  }

  return null;
}

/**
 * 智能解析路径字符串
 * @param {string} path - 路径字符串
 * @param {string} separator - 分隔符
 * @returns {string[]} 路径数组
 */
function parsePath(path, separator = '.') {
  const segments = [];
  let current = '';
  let inBracket = false;

  for (let i = 0; i < path.length; i++) {
    const char = path[i];

    if (char === '[') {
      if (current) {
        segments.push(current);
        current = '';
      }
      inBracket = true;
    } else if (char === ']') {
      if (inBracket && current) {
        segments.push(current);
        current = '';
      }
      inBracket = false;
    } else if (char === separator && !inBracket) {
      if (current) {
        segments.push(current);
        current = '';
      }
    } else {
      current += char;
    }
  }

  if (current) {
    segments.push(current);
  }

  return segments;
}

/**
 * 获取所有带注释的节点（包括数组项）
 */
export function getAllCommentsWithPaths(yamlContent) {
  const doc = parseDocument(yamlContent);
  const results = [];

  function traverse(node, path = [], context = {}) {
    if (!node) return;

    // 记录当前节点的注释（如果有）
    const currentComment = node?.comment || null;
    const currentCommentBefore = node?.commentBefore || null;

    if (node.items) {
      const isMap = node.items.some((item) => item.key !== undefined);

      if (isMap) {
        // 处理 Map
        node.items.forEach((pair) => {
          if (!pair.key) return;

          const key = pair.key.value || pair.key.toString();
          const currentPath = [...path, key];

          // 记录键的注释
          if (pair.key.comment || pair.key.commentBefore) {
            results.push({
              path: currentPath,
              pathString: formatPath(currentPath),
              type: 'key',
              comment: pair.key.comment || null,
              commentBefore: pair.key.commentBefore || null,
              value: key,
            });
          }

          // 记录值的注释
          if (pair.value && (pair.value.comment || pair.value.commentBefore)) {
            results.push({
              path: currentPath,
              pathString: formatPath(currentPath),
              type: 'value',
              comment: pair.value.comment || null,
              commentBefore: pair.value.commentBefore || null,
              value: pair.value.value !== undefined ? pair.value.value : pair.value.toString(),
              nodeType: pair.value.type,
            });
          }

          // 递归遍历值
          if (pair.value) {
            traverse(pair.value, currentPath, { parentKey: key });
          }
        });
      } else {
        // 处理 Seq（数组）
        node.items.forEach((item, index) => {
          const currentPath = [...path, String(index)];

          // 检查数组项的注释
          if (item) {
            // 标量数组项
            if (
              item.type === 'PLAIN' ||
              item.type === 'QUOTE_SINGLE' ||
              item.type === 'QUOTE_DOUBLE'
            ) {
              if (item.comment || item.commentBefore) {
                results.push({
                  path: currentPath,
                  pathString: formatPath(currentPath),
                  type: 'array-item',
                  comment: item.comment || null,
                  commentBefore: item.commentBefore || null,
                  value: item.value,
                  index: index,
                });
              }
            }
            // 复杂数组项（对象或嵌套数组）
            else if (item.comment || item.commentBefore) {
              results.push({
                path: currentPath,
                pathString: formatPath(currentPath),
                type: 'array-item',
                comment: item.comment || null,
                commentBefore: item.commentBefore || null,
                value: item.value !== undefined ? item.value : item.toString(),
                index: index,
              });
            }

            // 递归遍历
            traverse(item, currentPath, { parentIndex: index });
          }
        });
      }
    }
  }

  // 检查文档级别的注释
  if (doc.commentBefore) {
    results.push({
      path: [],
      pathString: '',
      type: 'document',
      comment: null,
      commentBefore: doc.commentBefore,
      value: null,
    });
  }

  traverse(doc.contents);
  return results;
}

/**
 * 格式化路径为字符串
 * @param {string[]} path - 路径数组
 * @returns {string} 格式化的路径字符串
 */
function formatPath(path) {
  return path
    .map((segment, index) => {
      // 如果是数字，表示数组索引，使用方括号
      if (/^\d+$/.test(segment)) {
        const prevSegment = path[index - 1];
        if (prevSegment) {
          return `[${segment}]`;
        }
      }
      // 如果包含特殊字符，使用引号包裹
      if (segment.includes('.') || segment.includes(':') || segment.includes(' ')) {
        return `["${segment}"]`;
      }
      return segment;
    })
    .join('.')
    .replace(/\.\[/g, '[');
}

/**
 * 高级查询器
 */
export class YamlCommentQueryAdvanced {
  constructor(yamlContent) {
    this.doc = parseDocument(yamlContent);
    this.commentsMap = new Map();
    this.structureMap = new Map();
    this._buildMaps();
  }

  _buildMaps() {
    const traverse = (node, path = [], depth = 0) => {
      if (!node) return;

      const pathKey = this._getPathKey(path);

      // 存储结构信息
      this.structureMap.set(pathKey, {
        path: [...path],
        depth: depth,
        type: node.type || 'unknown',
        hasItems: !!node.items,
        itemsCount: node.items?.length || 0,
      });

      if (node.items) {
        const isMap = node.items.some((item) => item.key !== undefined);

        if (isMap) {
          node.items.forEach((pair) => {
            if (!pair.key) return;

            const key = pair.key.value || pair.key.toString();
            const currentPath = [...path, key];
            const currentPathKey = this._getPathKey(currentPath);

            // 存储注释信息
            const commentInfo = {
              path: currentPath,
              pathString: formatPath(currentPath),
              value: pair.value?.value,
              comment: pair.value?.comment || null,
              commentBefore: pair.value?.commentBefore || null,
              keyComment: pair.key?.comment || null,
              keyCommentBefore: pair.key?.commentBefore || null,
              type: 'pair',
              nodeType: pair.value?.type,
              depth: depth + 1,
            };

            this.commentsMap.set(currentPathKey, commentInfo);

            if (pair.value) {
              traverse(pair.value, currentPath, depth + 1);
            }
          });
        } else {
          // 处理数组
          node.items.forEach((item, index) => {
            const currentPath = [...path, String(index)];
            const currentPathKey = this._getPathKey(currentPath);

            const commentInfo = {
              path: currentPath,
              pathString: formatPath(currentPath),
              value: item?.value,
              comment: item?.comment || null,
              commentBefore: item?.commentBefore || null,
              type: 'array-item',
              nodeType: item?.type,
              index: index,
              depth: depth + 1,
            };

            this.commentsMap.set(currentPathKey, commentInfo);

            traverse(item, currentPath, depth + 1);
          });
        }
      }
    };

    traverse(this.doc.contents);
  }

  _getPathKey(path) {
    return JSON.stringify(path);
  }

  /**
   * 获取指定路径的注释
   */
  get(path) {
    const pathArray = Array.isArray(path) ? path : parsePath(path);
    const pathKey = this._getPathKey(pathArray);
    return this.commentsMap.get(pathKey) || null;
  }

  /**
   * 获取指定路径的结构信息
   */
  getStructure(path) {
    const pathArray = Array.isArray(path) ? path : parsePath(path);
    const pathKey = this._getPathKey(pathArray);
    return this.structureMap.get(pathKey) || null;
  }

  /**
   * 查找路径模式匹配的所有节点
   */
  findByPattern(pattern) {
    const results = [];
    const regex = new RegExp(pattern);

    this.commentsMap.forEach((value, key) => {
      const pathStr = value.pathString;
      if (regex.test(pathStr)) {
        results.push(value);
      }
    });

    return results;
  }

  /**
   * 获取包含特定注释文本的节点
   */
  findByCommentText(searchText) {
    const results = [];
    const searchLower = searchText.toLowerCase();

    this.commentsMap.forEach((value) => {
      const comment =
        value.comment || value.commentBefore || value.keyComment || value.keyCommentBefore || '';
      if (comment.toLowerCase().includes(searchLower)) {
        results.push(value);
      }
    });

    return results;
  }
}
